package com.gujia.concurrency.example.aqs;


import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * CyclicBarrier:
 * 也是一个同步辅助类，它允许一组线程相互等待，直到到达某个公共屏障点
 * 用英文本身就是common barrier point，通过它可以完成多个线程之间相互等待。
 * 当每个线程都准备就绪后才能各自继续往下执行，后面的操作。当某个线程调用了await()方法增长该线程进入了等待状态。
 * 而且计数器执行的是加一操作，当计数器的值达到了初始值的时候，因为调用await()方法，进入等待状态的方法会被唤醒，
 * 继续执行他们后续的操作。可循环操作。
 * CountDownLatch 主要实现一个或者多个线程等待其他线程完成某项操作之后，才能继续往下执行
 * CyclicBarrier 主要实现多个线程之间的等待，直到所有的线程都满足了之后，才能继续执行后续的操作
 * （描述的是各个线程内部互相等待的关系），可用于计算发生错误，重新执行的情况
 */
public class CyclicBarrierExample2 {

    private  static int threadCount = 20;

    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
        @Override
        public void run() {
            System.out.println("sub thread is all ready !");
        }
    });
    public static void main(String[] args) {

        ExecutorService executorService = Executors.newCachedThreadPool();

        for(int i=0;i<20;i++){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int threadNum = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    test(threadNum);
                }
            });
        }

       executorService.shutdown();
    }

    public static void test(int i) {
        try{
            System.out.println("test "+i+" is running  !");
            Thread.sleep(100);

            cyclicBarrier.await(1, TimeUnit.SECONDS);
            System.out.println("test "+i+" is ready !");
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}
